﻿using IBM.WMQ;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace IBM.MQ.Test.Models
{
    public class MyIBMQueueManager
    {
        public Logger _logger = LogManager.GetCurrentClassLogger();

        /// <summary>
        /// Host主机
        /// </summary>
        public string Host { get; set; }

        /// <summary>
        /// 通道
        /// </summary>
        public string Channel { get; set; }

        /// <summary>
        /// 端口
        /// </summary>
        public int Port { get; set; }

        /// <summary>
        /// 队列管理器名称
        /// </summary>
        public string QueueManagerName { get; set; }

        /// <summary>
        /// 输出队列名称
        /// </summary>
        public string QueueName { get; set; }

        public MQQueueManager QMgr { get; set; }

        public MyIBMQueueManager()
        {

        }

        public bool Connect()
        {
            Hashtable env = new Hashtable();
            env.Add(MQC.HOST_NAME_PROPERTY, Host);
            env.Add(MQC.CHANNEL_PROPERTY, Channel);
            env.Add(MQC.PORT_PROPERTY, Port);

            try
            {
                QMgr = new MQQueueManager(QueueManagerName, env);
                Console.WriteLine("连接成功...");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("连接异常：" + ex.Message);
                return false;
            }
        }


        public void GetMessage()
        {
            try
            {
                int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT;

                MQMessage message = new MQMessage();

                MQQueue queue = QMgr.AccessQueue(QueueName, openOptions);

                MQGetMessageOptions gmo = new MQGetMessageOptions();
                gmo.Options = MQC.MQGMO_WAIT;
                gmo.WaitInterval = 30000;
                gmo.MatchOptions = MQC.MQMO_NONE;

                Console.WriteLine($"开始获取消息【{DateTime.Now}】：");
                queue.Get(message, gmo);

                var result = message.ReadString(message.MessageLength);
                _logger.Debug("获取消息：" + result);

                LoadXml(result);

                queue.Close();
            }
            catch (MQException e2)
            {
                if (e2.ReasonCode == MQC.MQRC_NO_MSG_AVAILABLE)
                {
                    Console.WriteLine("队列中没有消息或是已经取完");
                }
                else if (e2.ReasonCode == MQC.MQRC_CHANNEL_NOT_AVAILABLE
                  || e2.ReasonCode == MQC.MQRC_CONNECTION_BROKEN
                  || e2.ReasonCode == MQC.MQRC_CONNECTION_ERROR
                  || e2.ReasonCode == MQC.MQRC_CONNECTION_STOPPED
                  || e2.ReasonCode == MQC.MQRC_Q_MGR_QUIESCING)
                {
                    // 设定重新连接（接入厂商考虑重新连接设定）
                    Connect();
                    Console.WriteLine("队列管理器连接不可用，需要重新创建队列管理器!");
                }
                else
                {
                    _logger.Error($"获取异常：{e2.Message}");
                    Console.WriteLine("获取异常：" + e2.Message);
                }
                Thread.Sleep(30 * 1000);
            }
        }

        public void LoadXml(string xmlMessage)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlMessage);

            var headNode = doc.SelectSingleNode("msg/head");
            if (headNode == null)
            {
                return;
            }

            var msgId = headNode["msgId"].InnerText;
            if (msgId == "MS024")
            {
                //人员字典
                var rows = doc.SelectNodes("msg/body/row");
                if (rows.Count > 0)
                {
                    List<Userinfo> users = new List<Userinfo>();
                    foreach (XmlNode row in rows)
                    {
                        var user = new Userinfo()
                        {
                            Code = row["code"].InnerText,
                            Name = row["name"].InnerText,
                            PyCode = row["pyCode"].InnerText,
                            ItemVersion = row["itemVersion"].InnerText,
                            Genderid = row["genderid"].InnerText,
                            Statusid = row["statusid"].InnerText,
                            Orgid = row["orgid"].InnerText,
                            Orgname = row["orgname"].InnerText,
                            Birthday = row["birthday"].InnerText,
                            Emptelenum = row["emptelenum"].InnerText,
                            Email = row["email"].InnerText,
                            Orgid2 = row["orgid2"].InnerText,
                            Orgname2 = row["orgname2"].InnerText,
                            NationalIdentifier = row["nationalIdentifier"].InnerText,
                            Emppostseq = row["emppostseq"].InnerText,
                            Emppostname = row["emppostname"].InnerText,
                            Empprotitleid = row["empprotitleid"].InnerText,
                            Empprotitlename = row["empprotitlename"].InnerText,
                            Stopflag = row["stopflag"].InnerText,
                        };
                        var action = row.Attributes["action"].InnerText;
                        switch (action)
                        {
                            case "insert":
                                user.ActionType = ActionType.Insert;
                                break;
                            case "delete":
                                user.ActionType = ActionType.Delete;
                                break;
                            case "update":
                                user.ActionType = ActionType.Update;
                                break;
                        }

                        users.Add(user);
                    }
                    if (users.Count > 0)
                    {
                        PostData(users, "executeusers");
                    }
                }
            }
            else if (msgId == "MS025")
            {
                //科室字典
                //人员字典
                var rows = doc.SelectNodes("msg/body/row");
                if (rows.Count > 0)
                {
                    List<Unit> units = new List<Unit>();
                    foreach (XmlNode row in rows)
                    {
                        var unit = new Unit()
                        {
                            Code = row["code"].InnerText,
                            Name = row["name"].InnerText,
                            PyCode = row["pyCode"].InnerText,
                            ItemVersion = row["itemVersion"].InnerText,
                            Stopflag = row["stopflag"].InnerText,
                            Fullcode = row["fullcode"].InnerText,
                            Inputstr1 = row["inputstr1"].InnerText,
                            Orgaddr = row["orgaddr"].InnerText,
                            Orgtel1 = row["orgtel1"].InnerText,
                            Orgtel2 = row["orgtel2"].InnerText,
                            Upid = row["upid"].InnerText,
                        };
                        var action = row.Attributes["action"].InnerText;
                        switch (action)
                        {
                            case "insert":
                                unit.ActionType = ActionType.Insert;
                                break;
                            case "delete":
                                unit.ActionType = ActionType.Delete;
                                break;
                            case "update":
                                unit.ActionType = ActionType.Update;
                                break;
                        }

                        units.Add(unit);
                    }
                    if (units.Count > 0)
                    {
                        PostData(units, "executeunits");
                    }
                }
            }
        }


        public void PostData(object data,string type)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"http://localhost:5006/api/gzzoc/{type}");
            string strData = JsonConvert.SerializeObject(data);
            byte[] bytes = Encoding.UTF8.GetBytes(strData);
            req.Method = "POST";
            req.ContentLength = bytes.Length;
            req.ContentType = "application/json";
            try
            {
                Stream reqstream = req.GetRequestStream();
                reqstream.Write(bytes, 0, bytes.Length);
                //读数据
                req.Timeout = 300000;
                HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                StreamReader streamReader = new StreamReader(res.GetResponseStream(), Encoding.UTF8);
                string resultStr = streamReader.ReadToEnd();
                reqstream.Close();
                streamReader.Close();
                reqstream.Close();
                res.Close();
                Console.WriteLine("上传数据请求成功");

                return;
            }
            catch (Exception ex)
            {
                _logger.Error($"上传数据请求异常：{ex.Message}");
                Console.WriteLine("上传数据请求异常：" + ex.Message);
            }
        }

    }
}
